#ifndef _RING_BUFFER_H_
#define _RING_BUFFER_H_

#include <linux/kernel.h>

#define RINGBUFFER_DISTANCE(rb, a, b)   (((b) + (rb)->size - (a)) % (rb)->size)
#define RB_POS_MOV(rb, ori, off)        (((ori) + (off)) % (rb)->size)

typedef struct ringbuffer {
    u8* buffer;
    u32 size;
    u32 write;
    u32 read;
    u32 data_len;
} ringbuffer_t;

void     ringbuffer_reset(ringbuffer_t* fifo);
u32 ringbuffer_len(ringbuffer_t* fifo);
u32 ringbuffer_avail(ringbuffer_t* fifo);
bool     ringbuffer_is_empty(ringbuffer_t* fifo);
bool     ringbuffer_is_full(ringbuffer_t* fifo);

/*write to ringbuffer*/
u32 ringbuffer_in(ringbuffer_t* fifo, const void* in, u32 len);
u32 ringbuffer_in_with_limit(ringbuffer_t* fifo, const void* in, u32 len, u32 limit);

/*read to ringbuffer*/
u32 ringbuffer_out(ringbuffer_t* fifo, void* out, u32 len);

u32 ringbuffer_get_data(ringbuffer_t* fifo, void* outbuf, u32 start, u32 len);

/*pick from ringbuffer*/
u32 ringbuffer_pick(ringbuffer_t *fifo, u32 pos, void *out, u32 len);

#endif /* _RING_BUFFER_H_ */
